home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: delta / whiteline CD Series - delta.iso / progtool / c / egem_210 / egem / source / dragdrop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-25  |  4.9 KB  |  292 lines

  1.  
  2. #include "proto.h"
  3. #include <string.h>
  4.  
  5. #ifdef __MINT_LIB__
  6. #include <mintbind.h>
  7. #endif
  8.  
  9. #ifndef EACCDN
  10. #define EACCDN -36
  11. #endif
  12.  
  13. #ifndef SIGPIPE
  14. #define SIGPIPE 13
  15. #endif
  16.  
  17. #ifndef SIG_IGN
  18. #define SIG_IGN 1L
  19. #endif
  20.  
  21. #ifdef __MINT_LIB__
  22. #define SIGNAL    long
  23. #else
  24. #define SIGNAL    void *
  25. #endif
  26.  
  27. static char ourexts[DD_EXTSIZE] = "ARGS";
  28. static char pipename[] = "U:\\PIPE\\DRAGDROP.AA";
  29. static int any_ext;
  30. static long oldpipesig;
  31.  
  32. int _dd_available;
  33.  
  34. void SetDragDrop(int any,char *exts)
  35. {
  36.     any_ext = any;
  37.     strupr(strncpy(ourexts,exts,DD_EXTSIZE-1));
  38. }
  39.  
  40. static int ddcreate(int sendto,int win_id,int msx,int msy,int kstate,char exts[])
  41. {
  42.     reg int fd, msg[8];
  43.     long fd_mask;
  44.     char c;
  45.  
  46.     pipename[17] = pipename[18] = 'A';
  47.  
  48.     do
  49.     {
  50.         pipename[18]++;
  51.         if (pipename[18]>'Z')
  52.         {
  53.             pipename[17]++;
  54.             if (pipename[17]>'Z')
  55.                 break;
  56.             else
  57.                 pipename[18] = 'A';
  58.         }
  59.         fd = (int) Fcreate(pipename, FA_HIDDEN);
  60.     } while (fd==EACCDN);
  61.  
  62.     if (fd<0)
  63.         return (-2);
  64.  
  65.     msg[3] = win_id;
  66.     msg[4] = msx;
  67.     msg[5] = msy;
  68.     msg[6] = kstate;
  69.     msg[7] = (pipename[17]<<8)|pipename[18];
  70.     if (AvSendMsg(sendto, AP_DRAGDROP, msg)==FALSE)
  71.     {
  72.         Fclose(fd);
  73.         return (-1);
  74.     }
  75.  
  76.     fd_mask = 1L<<fd;
  77.     if (Fselect(DD_TIMEOUT,&fd_mask,0L,0L) && fd_mask && Fread(fd,1L,&c)==1 && c==DD_OK && Fread(fd,DD_EXTSIZE,exts)==DD_EXTSIZE)
  78.     {
  79.         oldpipesig = (long) Psignal(SIGPIPE, (SIGNAL) SIG_IGN);
  80.         return (fd);
  81.     }
  82.     else
  83.     {
  84.         Fclose(fd);
  85.         return (-1);
  86.     }
  87. }
  88.  
  89. static int ddstry(int fd, char *ext, char *name, long size)
  90. {
  91.     int hdrlen,namelen;
  92.     char c;
  93.  
  94.     namelen = (int) strlen(name)+1;
  95.     hdrlen = namelen+8;
  96.  
  97.     if (Fwrite(fd,2L,&hdrlen)!=2 || Fwrite(fd,4L,ext)!=4 || Fwrite(fd,4L,&size)!=4 || Fwrite(fd,namelen,name)!=namelen || Fread(fd,1L,&c)!=1)
  98.         return (DD_NAK);
  99.     else
  100.         return (c);
  101. }
  102.  
  103. static void ddclose(int fd)
  104. {
  105.     Psignal(SIGPIPE, (SIGNAL) oldpipesig);
  106.     Fclose(fd);
  107. }
  108.  
  109. static int ddopen(int ddnam,char *preferext)
  110. {
  111.     reg int fd;
  112.     char outbuf[DD_EXTSIZE+1];
  113.  
  114.     pipename[18] = (char) ddnam;
  115.     pipename[17] = (char) (ddnam>>8);
  116.  
  117.     fd = (int) Fopen(pipename,2);
  118.     if (fd<0)
  119.         return (fd);
  120.  
  121.     outbuf[0] = DD_OK;
  122.     strncpy(outbuf+1,preferext,DD_EXTSIZE);
  123.  
  124.     oldpipesig = (long) Psignal(SIGPIPE,(SIGNAL) SIG_IGN);
  125.     if (Fwrite(fd,DD_EXTSIZE+1,outbuf)!=DD_EXTSIZE+1)
  126.     {
  127.         ddclose(fd);
  128.         return (-1);
  129.     }
  130.     else
  131.         return (fd);
  132. }
  133.  
  134. static int ddrtry(int fd, char *name, char *whichext, long *size)
  135. {
  136.     int hdrlen,i;
  137.     char buf[80];
  138.  
  139.     if (Fread(fd,2L,&hdrlen)!=2 || hdrlen<9)
  140.         return (-1);
  141.  
  142.     if (Fread(fd,4L,whichext)!=4)
  143.         return (-1);
  144.  
  145.     whichext[4] = 0;
  146.     if (Fread(fd,4L,size)!=4)
  147.         return (-1);
  148.  
  149.     hdrlen -= 8;
  150.     i = min(hdrlen,DD_NAMEMAX);
  151.     if (Fread(fd,i,name)!=i)
  152.         return (-1);
  153.  
  154.     hdrlen -= i;
  155.     while (hdrlen>80)
  156.     {
  157.         Fread(fd,80L,buf);
  158.         hdrlen -= 80;
  159.     }
  160.  
  161.     if (hdrlen>0)
  162.         Fread(fd,hdrlen,buf);
  163.  
  164.     return (0);
  165. }
  166.  
  167. static int ddreply(int fd, int ack)
  168. {
  169.     char c = ack;
  170.  
  171.     if (Fwrite(fd,1L,&c)!=1)
  172.     {
  173.         ddclose(fd);
  174.         return (-1);
  175.     }
  176.     else
  177.         return (0);
  178. }
  179.  
  180. void _rec_ddmsg(int *msg)
  181. {
  182.     DRAG_DROP dd;
  183.     char txtname[DD_NAMEMAX],*mem,ext[5];
  184.     int fd;
  185.  
  186.     if (strlen(ourexts)<4)
  187.         return;
  188.  
  189.     dd.dd_originator = msg[1];
  190.     dd.dd_type = MINT_DRAG;
  191.     dd.dd_win = get_window(msg[3]);
  192.     dd.dd_mx = msg[4];
  193.     dd.dd_my = msg[5];
  194.     dd.dd_kstate = msg[6];
  195.  
  196.     if ((fd=ddopen(msg[7],ourexts))<0)
  197.         return;
  198.  
  199.     for(;;)
  200.     {
  201.         if (ddrtry(fd,txtname,ext,&dd.dd_size))
  202.         {
  203.             ddclose(fd);
  204.             return;
  205.         }
  206.         else
  207.         {
  208.             ext[4] = '\0';
  209.             memcpy(dd.dd_ext,ext,4);
  210.             strupr(ext);
  211.         }
  212.  
  213.         if (any_ext || strstr(ourexts,ext))
  214.         {
  215.             if ((mem=Malloc(dd.dd_size+1))==NULL)
  216.             {
  217.                 if (ddreply(fd, DD_LEN))
  218.                     return;
  219.                 continue;
  220.             }
  221.  
  222.             if (ddreply(fd,DD_OK))
  223.                 return;
  224.  
  225.             if (Fread(fd,dd.dd_size,mem)!=dd.dd_size)
  226.             {
  227.                 ddclose(fd);
  228.                 return;
  229.             }
  230.  
  231.             mem[dd.dd_size] = 0;
  232.             ddclose(fd);
  233.  
  234.             if (!strncmp(ext,"ARGS",4))
  235.             {
  236.                 dd.dd_args = mem;
  237.                 dd.dd_ext[0] = '\0';
  238.                 dd.dd_mem = NULL;
  239.                 dd.dd_size = 0;
  240.             }
  241.             else
  242.             {
  243.                 dd.dd_args = NULL;
  244.                 dd.dd_mem = mem;
  245.             }
  246.  
  247.             dd.dd_name = txtname;
  248.             _send_msg(&dd,0,OBJC_DRAGGED,0,0);
  249.  
  250.             Mfree(mem);
  251.             return;
  252.         }
  253.         else if (ddreply(fd, DD_EXT))
  254.             return;
  255.     }
  256. }
  257.  
  258. int SendDragDrop(int msx,int msy,int kstate,char *name,char *sp_ext,long size,char *data)
  259. {
  260.     int fd,sendto,win_id,dummy;
  261.     char recexts[DD_EXTSIZE],exts[5];
  262.  
  263.     if (!_dd_available)
  264.         return (NO_DD);
  265.  
  266.     memcpy(exts,sp_ext,4);
  267.     exts[4] = '\0';
  268.     strupr(exts);
  269.  
  270.     if ((win_id=wind_find(msx,msy))<=0 || !wind_xget(win_id,WF_OWNER,&sendto,&dummy,&dummy,&dummy) || sendto==ap_id)
  271.         return (NO_RECEIVER);
  272.  
  273.     switch (fd=ddcreate(sendto,win_id,msx,msy,kstate,recexts))
  274.     {
  275.     case -2:
  276.         return (NO_DD);
  277.     case -1:
  278.         return (DD_NAK);
  279.     }
  280.  
  281.     if ((dummy=ddstry(fd,exts,name,size))!=DD_OK)
  282.     {
  283.         ddclose(fd);
  284.         return (dummy);
  285.     }
  286.  
  287.     dummy = (Fwrite(fd,size,data)==size);
  288.     ddclose(fd);
  289.  
  290.     return ((dummy) ? DD_OK : DD_LEN);
  291. }
  292.